package com.woniuxy.zuul.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.woniuxy.commons.enums.ResultEnum;
import com.woniuxy.commons.util.ResponseResult;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author: yangtao
 * @date 2021/8/4 11:33
 * @Version 1.0
 */
@Component
public class LimitFilter extends ZuulFilter {
    //创建限流器，指定令牌数量
    private static final RateLimiter RATE_LIMITER=RateLimiter.create(500);

    //指定filter的类型
    @Override
    public String filterType() {
        //直接返回字符串
        return "pre";
    }

    //执行的顺序
    @Override
    public int filterOrder() {
        return -100;
    }

    //是否要过滤，如果返回true，才会执行run方法，如果是false，run方法永远不会执行
    @Override
    public boolean shouldFilter() {
        //编写判断过滤的条件，需要过滤的才执行run
        //得到上下文对象
        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        String uri = request.getRequestURI();
        System.out.println(uri);
        return true;
    }

    //编写处理过滤的业务逻辑，是否登录，鉴权，限流等操作
    @Override
    public Object run() throws ZuulException {
        //第一步：判断能否拿到令牌
        if (!RATE_LIMITER.tryAcquire()){
            //没拿到令牌，结束请求，返回结果
            RequestContext context = RequestContext.getCurrentContext();
            context.setSendZuulResponse(false);  //false表示不继续处理请求，到此为止
            //设置返回结果
            ResponseResult<String> responseResult=new ResponseResult<String>(500, ResultEnum.SYSTEM_BUSY,"服务器正忙，请稍后再试",null);
            //使用httpservletreponse返回结果
            HttpServletResponse response = context.getResponse();
            //设置想响应头
            response.setContentType("application/json;charset=utf-8");
            try {
                //将json转为json
                String json = new ObjectMapper().writeValueAsString(responseResult);
                //返回结果
                response.getWriter().write(json);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return null;
    }
}
